home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet internetowy / Przegladarki internetowe / Mozilla Seamonkey 1.0.5 pl / seamonkey-1.0.5.pl-PL.win32.installer.exe / MAIL.XPI / bin / chrome / messenger.jar / content / messenger / mail3PaneWindowCommands.js < prev    next >
Encoding:
JavaScript  |  2005-08-08  |  35.3 KB  |  1,188 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2.  * ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is Mozilla Communicator client code, released
  16.  * March 31, 1998.
  17.  *
  18.  * The Initial Developer of the Original Code is
  19.  * Netscape Communications Corporation.
  20.  * Portions created by the Initial Developer are Copyright (C) 1998-2000
  21.  * the Initial Developer. All Rights Reserved.
  22.  *
  23.  * Contributor(s):
  24.  *   Jan Varga <varga@ku.sk>
  25.  *   Hσkan Waara (hwaara@chello.se)
  26.  *
  27.  * Alternatively, the contents of this file may be used under the terms of
  28.  * either of the GNU General Public License Version 2 or later (the "GPL"),
  29.  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  30.  * in which case the provisions of the GPL or the LGPL are applicable instead
  31.  * of those above. If you wish to allow use of your version of this file only
  32.  * under the terms of either the GPL or the LGPL, and not to allow others to
  33.  * use your version of this file under the terms of the MPL, indicate your
  34.  * decision by deleting the provisions above and replace them with the notice
  35.  * and other provisions required by the GPL or the LGPL. If you do not delete
  36.  * the provisions above, a recipient may use your version of this file under
  37.  * the terms of any one of the MPL, the GPL or the LGPL.
  38.  *
  39.  * ***** END LICENSE BLOCK ***** */
  40.  
  41. var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  42. var gMessengerBundle = document.getElementById("bundle_messenger");
  43.  
  44. // Controller object for folder pane
  45. var FolderPaneController =
  46. {
  47.    supportsCommand: function(command)
  48.     {
  49.         switch ( command )
  50.         {
  51.             case "cmd_delete":
  52.             case "button_delete":
  53.             //case "cmd_selectAll": the folder pane currently only handles single selection
  54.             case "cmd_cut":
  55.             case "cmd_copy":
  56.             case "cmd_paste":
  57.                 return true;
  58.                 
  59.             default:
  60.                 return false;
  61.         }
  62.     },
  63.  
  64.     isCommandEnabled: function(command)
  65.     {
  66.     if (IsFakeAccount()) 
  67.       return false;
  68.  
  69.         switch ( command )
  70.         {
  71.             case "cmd_cut":
  72.             case "cmd_copy":
  73.             case "cmd_paste":
  74.                 return false;
  75.             case "cmd_delete":
  76.             case "button_delete":
  77.             if ( command == "cmd_delete" )
  78.                 goSetMenuValue(command, 'valueFolder');
  79.       var folderTree = GetFolderTree();
  80.       var startIndex = {};
  81.       var endIndex = {};
  82.       folderTree.view.selection.getRangeAt(0, startIndex, endIndex);
  83.       if (startIndex.value >= 0) {
  84.         var canDeleteThisFolder;
  85.                 var specialFolder = null;
  86.                 var isServer = null;
  87.                 var serverType = null;
  88.                 try {
  89.           var folderResource = GetFolderResource(folderTree, startIndex.value);
  90.           specialFolder = GetFolderAttribute(folderTree, folderResource, "SpecialFolder");
  91.           isServer = GetFolderAttribute(folderTree, folderResource, "IsServer");
  92.           serverType = GetFolderAttribute(folderTree, folderResource, "ServerType");
  93.           if (serverType == "nntp") {
  94.                      if ( command == "cmd_delete" ) {
  95.                           goSetMenuValue(command, 'valueNewsgroup');
  96.                           goSetAccessKey(command, 'valueNewsgroupAccessKey');
  97.             }
  98.           }
  99.                 }
  100.                 catch (ex) {
  101.                     //dump("specialFolder failure: " + ex + "\n");
  102.                 } 
  103.         if (specialFolder == "Inbox" || specialFolder == "Trash" || specialFolder == "Drafts" ||
  104.             specialFolder == "Sent" || specialFolder == "Templates" || specialFolder == "Unsent Messages" ||
  105.             (specialFolder == "Junk" && !CanRenameDeleteJunkMail(GetSelectedFolderURI())) || isServer == "true")
  106.           canDeleteThisFolder = false;
  107.         else
  108.           canDeleteThisFolder = true;
  109.         return canDeleteThisFolder && isCommandEnabled(command);
  110.       }
  111.             else
  112.                 return false;
  113.  
  114.             default:
  115.                 return false;
  116.         }
  117.     },
  118.  
  119.     doCommand: function(command)
  120.     {
  121.     // if the user invoked a key short cut then it is possible that we got here for a command which is
  122.     // really disabled. kick out if the command should be disabled.
  123.     if (!this.isCommandEnabled(command)) return;
  124.  
  125.         switch ( command )
  126.         {
  127.             case "cmd_delete":
  128.             case "button_delete":
  129.                 MsgDeleteFolder();
  130.                 break;
  131.         }
  132.     },
  133.     
  134.     onEvent: function(event)
  135.     {
  136.     }
  137. };
  138.  
  139. // DefaultController object (handles commands when one of the trees does not have focus)
  140. var DefaultController =
  141. {
  142.    supportsCommand: function(command)
  143.     {
  144.  
  145.         switch ( command )
  146.         {
  147.       case "cmd_createFilterFromPopup":
  148.             case "cmd_close":
  149.             case "cmd_reply":
  150.             case "button_reply":
  151.             case "cmd_replySender":
  152.             case "cmd_replyGroup":
  153.             case "cmd_replyall":
  154.             case "button_replyall":
  155.             case "cmd_forward":
  156.             case "button_forward":
  157.             case "cmd_forwardInline":
  158.             case "cmd_forwardAttachment":
  159.             case "cmd_editAsNew":
  160.       case "cmd_createFilterFromMenu":
  161.             case "cmd_delete":
  162.             case "button_delete":
  163.       case "button_junk":
  164.             case "cmd_shiftDelete":
  165.             case "cmd_nextMsg":
  166.       case "button_next":
  167.             case "cmd_nextUnreadMsg":
  168.             case "cmd_nextFlaggedMsg":
  169.             case "cmd_nextUnreadThread":
  170.             case "cmd_previousMsg":
  171.             case "cmd_previousUnreadMsg":
  172.             case "cmd_previousFlaggedMsg":
  173.       case "cmd_goStartPage":
  174.             case "cmd_viewAllMsgs":
  175.             case "cmd_viewUnreadMsgs":
  176.       case "cmd_viewThreadsWithUnread":
  177.       case "cmd_viewWatchedThreadsWithUnread":
  178.       case "cmd_viewIgnoredThreads":
  179.       case "cmd_undo":
  180.       case "cmd_redo":
  181.             case "cmd_expandAllThreads":
  182.             case "cmd_collapseAllThreads":
  183.             case "cmd_renameFolder":
  184.             case "cmd_sendUnsentMsgs":
  185.             case "cmd_openMessage":
  186.       case "button_print":
  187.             case "cmd_print":
  188.             case "cmd_printpreview":
  189.             case "cmd_printSetup":
  190.             case "cmd_saveAsFile":
  191.             case "cmd_saveAsTemplate":
  192.       case "cmd_properties":
  193.             case "cmd_viewPageSource":
  194.             case "cmd_setFolderCharset":
  195.             case "cmd_reload":
  196.       case "button_getNewMessages":
  197.             case "cmd_getNewMessages":
  198.       case "cmd_getMsgsForAuthAccounts":
  199.             case "cmd_getNextNMessages":
  200.             case "cmd_find":
  201.             case "cmd_findAgain":
  202.             case "cmd_findPrev":
  203.       case "cmd_search":
  204.       case "button_mark":
  205.             case "cmd_markAsRead":
  206.             case "cmd_markAllRead":
  207.             case "cmd_markThreadAsRead":
  208.             case "cmd_markReadByDate":
  209.             case "cmd_markAsFlagged":
  210.             case "cmd_markAsJunk":
  211.             case "cmd_markAsNotJunk":
  212.       case "cmd_recalculateJunkScore":
  213.       case "cmd_markAsShowRemote":
  214.       case "cmd_markAsNotPhish":
  215.       case "cmd_applyFilters":
  216.       case "cmd_runJunkControls":
  217.       case "cmd_deleteJunk":
  218.       case "cmd_label0":
  219.       case "cmd_label1":
  220.       case "cmd_label2":
  221.       case "cmd_label3":
  222.       case "cmd_label4":
  223.       case "cmd_label5":
  224.       case "button_file":
  225.             case "cmd_file":
  226.             case "cmd_emptyTrash":
  227.             case "cmd_compactFolder":
  228.         case "cmd_settingsOffline":
  229.       case "cmd_close":
  230.       case "cmd_selectAll":
  231.       case "cmd_selectThread":
  232.       case "cmd_selectFlagged":
  233.                 return true;
  234.       case "cmd_downloadFlagged":
  235.       case "cmd_downloadSelected":
  236.       case "cmd_synchronizeOffline":
  237.         return(CheckOnline());
  238.  
  239.       case "cmd_watchThread":
  240.       case "cmd_killThread":
  241.         return(isNewsURI(GetFirstSelectedMessage()));
  242.  
  243.             default:
  244.                 return false;
  245.         }
  246.     },
  247.  
  248.   isCommandEnabled: function(command)
  249.   {
  250.     var enabled = new Object();
  251.     enabled.value = false;
  252.     var checkStatus = new Object();
  253.  
  254.     if (IsFakeAccount()) 
  255.       return false;
  256.  
  257.     switch ( command )
  258.     {
  259.       case "cmd_delete":
  260.         UpdateDeleteCommand();
  261.         // fall through
  262.       case "button_delete":
  263.         if (gDBView)
  264.           gDBView.getCommandStatus(nsMsgViewCommandType.deleteMsg, enabled, checkStatus);
  265.         return enabled.value;
  266.       case "cmd_shiftDelete":
  267.         if (gDBView)
  268.           gDBView.getCommandStatus(nsMsgViewCommandType.deleteNoTrash, enabled, checkStatus);
  269.         return enabled.value;
  270.       case "button_junk":
  271.         UpdateJunkToolbarButton();
  272.         if (gDBView)
  273.           gDBView.getCommandStatus(nsMsgViewCommandType.junk, enabled, checkStatus);
  274.         return enabled.value;
  275.       case "cmd_killThread":
  276.         return GetNumSelectedMessages() > 0;
  277.       case "cmd_watchThread":
  278.         if (gDBView)
  279.           gDBView.getCommandStatus(nsMsgViewCommandType.toggleThreadWatched, enabled, checkStatus);
  280.         return enabled.value;
  281.       case "cmd_createFilterFromPopup":
  282.       case "cmd_createFilterFromMenu":
  283.         var loadedFolder = GetLoadedMsgFolder();
  284.         if (!(loadedFolder && loadedFolder.server.canHaveFilters))
  285.           return false;   // else fall thru
  286.       case "cmd_saveAsFile":
  287.       case "cmd_saveAsTemplate":
  288.           if ( GetNumSelectedMessages() > 1)
  289.           return false;   // else fall thru
  290.       case "cmd_reply":
  291.       case "button_reply":
  292.       case "cmd_replySender":
  293.       case "cmd_replyGroup":
  294.       case "cmd_replyall":
  295.       case "button_replyall":
  296.       case "cmd_forward":
  297.       case "button_forward":
  298.       case "cmd_forwardInline":
  299.       case "cmd_forwardAttachment":
  300.       case "cmd_editAsNew":
  301.       case "cmd_openMessage":
  302.       case "button_print":
  303.       case "cmd_print":
  304.       case "cmd_viewPageSource":
  305.       case "cmd_reload":
  306.         if (GetNumSelectedMessages() > 0)
  307.         {
  308.           if (gDBView)
  309.           {
  310.             gDBView.getCommandStatus(nsMsgViewCommandType.cmdRequiringMsgBody, enabled, checkStatus);
  311.             return enabled.value;
  312.           }
  313.         }
  314.         return false;
  315.       case "cmd_printpreview":
  316.           if ( GetNumSelectedMessages() == 1 && gDBView)
  317.         {
  318.            gDBView.getCommandStatus(nsMsgViewCommandType.cmdRequiringMsgBody, enabled, checkStatus);
  319.            return enabled.value;
  320.         }
  321.         return false;
  322.       case "cmd_printSetup":
  323.         return true;
  324.       case "cmd_markAsFlagged":
  325.       case "button_file":
  326.       case "cmd_file":
  327.         return (GetNumSelectedMessages() > 0);
  328.       case "cmd_markAsJunk":
  329.       case "cmd_markAsNotJunk":
  330.       case "cmd_recalculateJunkScore":
  331.         // can't do news on junk yet.
  332.         return (GetNumSelectedMessages() > 0 && !isNewsURI(GetFirstSelectedMessage()));
  333.       case "cmd_markAsShowRemote":
  334.         return (GetNumSelectedMessages() > 0 && checkMsgHdrPropertyIsNot("remoteContentPolicy", kAllowRemoteContent));
  335.       case "cmd_markAsNotPhish":
  336.         return (GetNumSelectedMessages() > 0 && checkMsgHdrPropertyIsNot("notAPhishMessage", kNotAPhishMessage));
  337.       case "cmd_applyFilters":
  338.         if (gDBView)
  339.           gDBView.getCommandStatus(nsMsgViewCommandType.applyFilters, enabled, checkStatus);
  340.         return enabled.value;
  341.       case "cmd_runJunkControls":
  342.         if (gDBView)
  343.           gDBView.getCommandStatus(nsMsgViewCommandType.runJunkControls, enabled, checkStatus);
  344.         return enabled.value;
  345.       case "cmd_deleteJunk":
  346.         if (gDBView)
  347.           gDBView.getCommandStatus(nsMsgViewCommandType.deleteJunk, enabled, checkStatus);
  348.         return enabled.value;
  349.       case "button_mark":
  350.       case "cmd_markAsRead":
  351.       case "cmd_markThreadAsRead":
  352.       case "cmd_label0":
  353.       case "cmd_label1":
  354.       case "cmd_label2":
  355.       case "cmd_label3":
  356.       case "cmd_label4":
  357.       case "cmd_label5":
  358.         return GetNumSelectedMessages() > 0;
  359.       case "button_next":
  360.         return IsViewNavigationItemEnabled();
  361.       case "cmd_nextMsg":
  362.       case "cmd_nextUnreadMsg":
  363.       case "cmd_nextUnreadThread":
  364.       case "cmd_previousMsg":
  365.       case "cmd_previousUnreadMsg":
  366.         return IsViewNavigationItemEnabled();
  367.       case "cmd_goStartPage":
  368.         return pref.getBoolPref("mailnews.start_page.enabled") && !IsMessagePaneCollapsed();
  369.       case "cmd_markAllRead":
  370.       case "cmd_markReadByDate":
  371.         return IsFolderSelected();
  372.       case "cmd_find":
  373.       case "cmd_findAgain":
  374.       case "cmd_findPrev":
  375.         return IsMessageDisplayedInMessagePane();
  376.         break;
  377.       case "cmd_search":
  378.         return IsCanSearchMessagesEnabled();
  379.       case "cmd_selectAll":
  380.       case "cmd_selectFlagged":
  381.         return gDBView != null;
  382.       // these are enabled on when we are in threaded mode
  383.       case "cmd_selectThread":
  384.         if (GetNumSelectedMessages() <= 0) return false;
  385.       case "cmd_expandAllThreads":
  386.       case "cmd_collapseAllThreads":
  387.         if (!gDBView || !gDBView.supportsThreading) 
  388.           return false;
  389.         return (gDBView.viewFlags & nsMsgViewFlagsType.kThreadedDisplay);
  390.         break;
  391.       case "cmd_nextFlaggedMsg":
  392.       case "cmd_previousFlaggedMsg":
  393.         return IsViewNavigationItemEnabled();
  394.       case "cmd_viewAllMsgs":
  395.       case "cmd_viewUnreadMsgs":
  396.       case "cmd_viewThreadsWithUnread":
  397.       case "cmd_viewWatchedThreadsWithUnread":
  398.       case "cmd_viewIgnoredThreads":
  399.         return gDBView;
  400.       case "cmd_stop":
  401.         return true;
  402.       case "cmd_undo":
  403.       case "cmd_redo":
  404.           return SetupUndoRedoCommand(command);
  405.       case "cmd_renameFolder":
  406.         return IsRenameFolderEnabled();
  407.       case "cmd_sendUnsentMsgs":
  408.         return IsSendUnsentMsgsEnabled(null);
  409.       case "cmd_properties":
  410.         return IsPropertiesEnabled(command);
  411.       case "button_getNewMessages":
  412.       case "cmd_getNewMessages":
  413.       case "cmd_getMsgsForAuthAccounts":
  414.         return IsGetNewMessagesEnabled();
  415.       case "cmd_getNextNMessages":
  416.         return IsGetNextNMessagesEnabled();
  417.       case "cmd_emptyTrash":
  418.         return IsEmptyTrashEnabled();
  419.       case "cmd_compactFolder":
  420.         return IsCompactFolderEnabled();
  421.       case "cmd_setFolderCharset":
  422.         return IsFolderCharsetEnabled();
  423.       case "cmd_close":
  424.         return true;
  425.       case "cmd_downloadFlagged":
  426.         return(CheckOnline());
  427.       case "cmd_downloadSelected":
  428.         return (IsFolderSelected() && CheckOnline() && GetNumSelectedMessages() > 0);
  429.       case "cmd_synchronizeOffline":
  430.         return CheckOnline() && IsAccountOfflineEnabled();       
  431.       case "cmd_settingsOffline":
  432.         return IsAccountOfflineEnabled();
  433.       default:
  434.         return false;
  435.     }
  436.     return false;
  437.   },
  438.  
  439.     doCommand: function(command)
  440.     {
  441.     // if the user invoked a key short cut then it is possible that we got here for a command which is
  442.     // really disabled. kick out if the command should be disabled.
  443.     if (!this.isCommandEnabled(command)) return;
  444.    
  445.         switch ( command )
  446.         {
  447.             case "cmd_close":
  448.                 CloseMailWindow();
  449.                 break;
  450.       case "button_getNewMessages":
  451.             case "cmd_getNewMessages":
  452.                 MsgGetMessage();
  453.                 break;
  454.       case "cmd_getMsgsForAuthAccounts":
  455.         MsgGetMessagesForAllAuthenticatedAccounts();
  456.         break;
  457.             case "cmd_getNextNMessages":
  458.                 MsgGetNextNMessages();
  459.                 break;
  460.             case "cmd_reply":
  461.                 MsgReplyMessage(null);
  462.                 break;
  463.             case "cmd_replySender":
  464.                 MsgReplySender(null);
  465.                 break;
  466.             case "cmd_replyGroup":
  467.                 MsgReplyGroup(null);
  468.                 break;
  469.             case "cmd_replyall":
  470.                 MsgReplyToAllMessage(null);
  471.                 break;
  472.             case "cmd_forward":
  473.                 MsgForwardMessage(null);
  474.                 break;
  475.             case "cmd_forwardInline":
  476.                 MsgForwardAsInline(null);
  477.                 break;
  478.             case "cmd_forwardAttachment":
  479.                 MsgForwardAsAttachment(null);
  480.                 break;
  481.             case "cmd_editAsNew":
  482.                 MsgEditMessageAsNew();
  483.                 break;
  484.       case "cmd_createFilterFromMenu":
  485.         MsgCreateFilter();
  486.         break;   
  487.       case "cmd_createFilterFromPopup":
  488.         CreateFilter(document.popupNode);
  489.         break;
  490.             case "button_delete":
  491.             case "cmd_delete":
  492.         // if the user deletes a message before its mark as read timer goes off, we should mark it as read
  493.         // this ensures that we clear the biff indicator from the system tray when the user deletes the new message
  494.         if (gMarkViewedMessageAsReadTimer) 
  495.         {
  496.           MarkCurrentMessageAsRead();
  497.           ClearPendingReadTimer();
  498.         }
  499.         SetNextMessageAfterDelete();
  500.         gDBView.doCommand(nsMsgViewCommandType.deleteMsg);
  501.                 break;
  502.             case "cmd_shiftDelete":
  503.         if (gMarkViewedMessageAsReadTimer) 
  504.         {
  505.           MarkCurrentMessageAsRead();
  506.           ClearPendingReadTimer();
  507.         }
  508.         SetNextMessageAfterDelete();
  509.         gDBView.doCommand(nsMsgViewCommandType.deleteNoTrash);
  510.                 break;
  511.       case "cmd_killThread":
  512.         /* kill thread kills the thread and then does a next unread */
  513.           GoNextMessage(nsMsgNavigationType.toggleThreadKilled, true);
  514.         break;
  515.       case "cmd_watchThread":
  516.         gDBView.doCommand(nsMsgViewCommandType.toggleThreadWatched);
  517.         break;
  518.       case "button_next":
  519.             case "cmd_nextUnreadMsg":
  520.                 MsgNextUnreadMessage();
  521.                 break;
  522.             case "cmd_nextUnreadThread":
  523.                 MsgNextUnreadThread();
  524.                 break;
  525.             case "cmd_nextMsg":
  526.                 MsgNextMessage();
  527.                 break;
  528.             case "cmd_nextFlaggedMsg":
  529.                 MsgNextFlaggedMessage();
  530.                 break;
  531.             case "cmd_previousMsg":
  532.                 MsgPreviousMessage();
  533.                 break;
  534.             case "cmd_previousUnreadMsg":
  535.                 MsgPreviousUnreadMessage();
  536.                 break;
  537.             case "cmd_previousFlaggedMsg":
  538.                 MsgPreviousFlaggedMessage();
  539.                 break;
  540.       case "cmd_goStartPage":
  541.         HideMessageHeaderPane();
  542.         loadStartPage();
  543.         break;
  544.             case "cmd_viewAllMsgs":
  545.       case "cmd_viewThreadsWithUnread":
  546.       case "cmd_viewWatchedThreadsWithUnread":
  547.             case "cmd_viewUnreadMsgs":
  548.       case "cmd_viewIgnoredThreads":
  549.                 SwitchView(command);
  550.                 break;
  551.             case "cmd_undo":
  552.                 messenger.Undo(msgWindow);
  553.                 break;
  554.             case "cmd_redo":
  555.                 messenger.Redo(msgWindow);
  556.                 break;
  557.             case "cmd_expandAllThreads":
  558.                 gDBView.doCommand(nsMsgViewCommandType.expandAll);
  559.                 break;
  560.             case "cmd_collapseAllThreads":
  561.                 gDBView.doCommand(nsMsgViewCommandType.collapseAll);
  562.                 break;
  563.             case "cmd_renameFolder":
  564.                 MsgRenameFolder();
  565.                 return;
  566.             case "cmd_sendUnsentMsgs":
  567.                 MsgSendUnsentMsgs();
  568.                 return;
  569.             case "cmd_openMessage":
  570.                 MsgOpenSelectedMessages();
  571.                 return;
  572.             case "cmd_printSetup":
  573.               NSPrintSetup();
  574.               return;
  575.             case "cmd_print":
  576.                 PrintEnginePrint();
  577.                 return;
  578.             case "cmd_printpreview":
  579.                 PrintEnginePrintPreview();
  580.                 return;
  581.             case "cmd_saveAsFile":
  582.                 MsgSaveAsFile();
  583.                 return;
  584.             case "cmd_saveAsTemplate":
  585.                 MsgSaveAsTemplate();
  586.                 return;
  587.             case "cmd_viewPageSource":
  588.                 MsgViewPageSource();
  589.                 return;
  590.             case "cmd_setFolderCharset":
  591.                 MsgSetFolderCharset();
  592.                 return;
  593.             case "cmd_reload":
  594.                 MsgReload();
  595.                 return;
  596.             case "cmd_find":
  597.                 MsgFind();
  598.                 return;
  599.             case "cmd_findAgain":
  600.                 MsgFindAgain(false);
  601.                 return;
  602.             case "cmd_findPrev":
  603.                 MsgFindAgain(true);
  604.                 return;
  605.       case "cmd_properties":
  606.         MsgFolderProperties();
  607.         return;
  608.       case "cmd_search":
  609.         MsgSearchMessages();
  610.         return;
  611.       case "button_mark":
  612.             case "cmd_markAsRead":
  613.                 MsgMarkMsgAsRead(null);
  614.                 return;
  615.             case "cmd_markThreadAsRead":
  616.                 MsgMarkThreadAsRead();
  617.                 return;
  618.             case "cmd_markAllRead":
  619.         gDBView.doCommand(nsMsgViewCommandType.markAllRead);
  620.                 return;
  621.             case "cmd_markReadByDate":
  622.         MsgMarkReadByDate();
  623.         return;
  624.       case "button_junk":
  625.         MsgJunk();
  626.         return;
  627.       case "cmd_stop":
  628.         MsgStop();
  629.         return;
  630.             case "cmd_markAsFlagged":
  631.                 MsgMarkAsFlagged(null);
  632.                 return;
  633.             case "cmd_markAsJunk":
  634.         JunkSelectedMessages(true);
  635.                 return;
  636.             case "cmd_markAsNotJunk":
  637.         JunkSelectedMessages(false);
  638.                 return;
  639.       case "cmd_recalculateJunkScore":
  640.         analyzeMessagesForJunk();
  641.         return;
  642.       case "cmd_markAsShowRemote":
  643.         LoadMsgWithRemoteContent();
  644.         return;
  645.       case "cmd_markAsNotPhish":
  646.         MsgIsNotAScam();
  647.         return;
  648.       case "cmd_applyFilters":
  649.         MsgApplyFilters(null);
  650.         return;
  651.       case "cmd_runJunkControls":
  652.         filterFolderForJunk();
  653.         return;
  654.       case "cmd_deleteJunk":
  655.         deleteJunkInFolder();
  656.         return;
  657.       case "cmd_label0":
  658.         gDBView.doCommand(nsMsgViewCommandType.label0);
  659.                  return;
  660.       case "cmd_label1":
  661.         gDBView.doCommand(nsMsgViewCommandType.label1);
  662.         return; 
  663.       case "cmd_label2":
  664.         gDBView.doCommand(nsMsgViewCommandType.label2);
  665.         return; 
  666.       case "cmd_label3":
  667.         gDBView.doCommand(nsMsgViewCommandType.label3);
  668.         return; 
  669.       case "cmd_label4":
  670.         gDBView.doCommand(nsMsgViewCommandType.label4);
  671.         return; 
  672.       case "cmd_label5":
  673.         gDBView.doCommand(nsMsgViewCommandType.label5);
  674.         return; 
  675.             case "cmd_emptyTrash":
  676.                 MsgEmptyTrash();
  677.                 return;
  678.             case "cmd_compactFolder":
  679.                 MsgCompactFolder(true);
  680.                 return;
  681.             case "cmd_downloadFlagged":
  682.                 MsgDownloadFlagged();
  683.                 break;
  684.             case "cmd_downloadSelected":
  685.                 MsgDownloadSelected();
  686.                 break;
  687.             case "cmd_synchronizeOffline":
  688.                 MsgSynchronizeOffline();
  689.                 break;
  690.             case "cmd_settingsOffline":
  691.                 MsgSettingsOffline();
  692.                 break;
  693.             case "cmd_selectAll":
  694.                 // move the focus so the user can delete the newly selected messages, not the folder
  695.                 SetFocusThreadPane();
  696.                 // if in threaded mode, the view will expand all before selecting all
  697.                 gDBView.doCommand(nsMsgViewCommandType.selectAll)
  698.                 if (gDBView.numSelected != 1) {
  699.                     setTitleFromFolder(gDBView.msgFolder,null);
  700.                     ClearMessagePane();
  701.                 }
  702.                 break;
  703.             case "cmd_selectThread":
  704.                 gDBView.doCommand(nsMsgViewCommandType.selectThread);
  705.                 break;
  706.       case "cmd_selectFlagged":
  707.         gDBView.doCommand(nsMsgViewCommandType.selectFlagged);
  708.         break;
  709.         }
  710.     },
  711.     
  712.     onEvent: function(event)
  713.     {
  714.         // on blur events set the menu item texts back to the normal values
  715.         if ( event == 'blur' )
  716.         {
  717.             goSetMenuValue('cmd_undo', 'valueDefault');
  718.             goSetMenuValue('cmd_redo', 'valueDefault');
  719.         }
  720.     }
  721. };
  722.  
  723. function GetNumSelectedMessages()
  724. {
  725.     try {
  726.         return gDBView.numSelected;
  727.     }
  728.     catch (ex) {
  729.         return 0;
  730.     }
  731. }
  732.  
  733. var gLastFocusedElement=null;
  734.  
  735. function FocusRingUpdate_Mail()
  736. {
  737.   // WhichPaneHasFocus() uses on top.document.commandDispatcher.focusedElement
  738.   // to determine which pane has focus
  739.   // if the focusedElement is null, we're here on a blur.
  740.   // nsFocusController::Blur() calls nsFocusController::SetFocusedElement(null), 
  741.   // which will update any commands listening for "focus".
  742.   // we really only care about nsFocusController::Focus() happens, 
  743.   // which calls nsFocusController::SetFocusedElement(element)
  744.   var currentFocusedElement = WhichPaneHasFocus();
  745.       
  746.     if (currentFocusedElement != gLastFocusedElement) {
  747.     if (currentFocusedElement)
  748.       currentFocusedElement.setAttribute("focusring", "true");
  749.     
  750.     if (gLastFocusedElement)
  751.       gLastFocusedElement.removeAttribute("focusring");
  752.  
  753.     gLastFocusedElement = currentFocusedElement;
  754.  
  755.     // since we just changed the pane with focus we need to update the toolbar to reflect this
  756.     // XXX TODO
  757.     // can we optimize
  758.     // and just update cmd_delete and button_delete?
  759.     UpdateMailToolbar("focus");
  760.   }
  761. }
  762.  
  763. function WhichPaneHasFocus()
  764. {
  765.   var threadTree = GetThreadTree();
  766.   var folderTree = GetFolderTree();
  767.   var messagePane = GetMessagePane();
  768.     
  769.   if (top.document.commandDispatcher.focusedWindow == GetMessagePaneFrame())
  770.     return messagePane;
  771.  
  772.     var currentNode = top.document.commandDispatcher.focusedElement;    
  773.     while (currentNode) {
  774.     if (currentNode === threadTree ||
  775.         currentNode === folderTree ||
  776.         currentNode === messagePane)
  777.       return currentNode;
  778.                 
  779.         currentNode = currentNode.parentNode;
  780.   }
  781.     
  782.     return null;
  783. }
  784.  
  785. function SetupCommandUpdateHandlers()
  786. {
  787.     var widget;
  788.     
  789.     // folder pane
  790.     widget = GetFolderTree();
  791.     if ( widget )
  792.         widget.controllers.appendController(FolderPaneController);
  793.     
  794.     top.controllers.insertControllerAt(0, DefaultController);
  795. }
  796.  
  797. function IsSendUnsentMsgsEnabled(folderResource)
  798. {
  799.   var identity;
  800.  
  801.   if (messenger.sendingUnsentMsgs) // if we're currently sending unsent msgs, disable this cmd.
  802.     return false;
  803.   try {
  804.     if (folderResource) {
  805.       // if folderResource is non-null, it is
  806.       // resource for the "Unsent Messages" folder
  807.       // we're here because we've done a right click on the "Unsent Messages"
  808.       // folder (context menu)
  809.       var msgFolder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  810.       return (msgFolder.getTotalMessages(false) > 0);
  811.     }
  812.     else {
  813.       var folders = GetSelectedMsgFolders();
  814.       if (folders.length > 0) {
  815.         identity = getIdentityForServer(folders[0].server);
  816.       }
  817.     }
  818.   }
  819.   catch (ex) {
  820.     dump("ex = " + ex + "\n");
  821.     identity = null;
  822.   }
  823.  
  824.   try {
  825.     if (!identity) {
  826.       var am = Components.classes["@mozilla.org/messenger/account-manager;1"].getService(Components.interfaces.nsIMsgAccountManager);
  827.       identity = am.defaultAccount.defaultIdentity;
  828.     }
  829.  
  830.     var msgSendlater = Components.classes["@mozilla.org/messengercompose/sendlater;1"].getService(Components.interfaces.nsIMsgSendLater);
  831.     var unsentMsgsFolder = msgSendlater.getUnsentMessagesFolder(identity);
  832.     return (unsentMsgsFolder.getTotalMessages(false) > 0);
  833.   }
  834.   catch (ex) {
  835.     dump("ex = " + ex + "\n");
  836.   }
  837.   return false;
  838. }
  839.  
  840. function IsRenameFolderEnabled()
  841. {
  842.     var folderTree = GetFolderTree();
  843.     var selection = folderTree.view.selection;
  844.     if (selection.count == 1)
  845.     {
  846.         var startIndex = {};
  847.         var endIndex = {};
  848.         selection.getRangeAt(0, startIndex, endIndex);
  849.         var folderResource = GetFolderResource(folderTree, startIndex.value);
  850.         var canRename = GetFolderAttribute(folderTree, folderResource, "CanRename") == "true";
  851.         return canRename && isCommandEnabled("cmd_renameFolder");
  852.     }
  853.     else
  854.         return false;
  855. }
  856.  
  857. function IsCanSearchMessagesEnabled()
  858. {
  859.   var folder = GetMsgFolderFromUri(GetSelectedFolderURI(), false);
  860.   var isVirtualFolder = folder.flags & MSG_FOLDER_FLAG_VIRTUAL;
  861.   return folder.server.canSearchMessages && !isVirtualFolder;
  862. }
  863.  
  864. function IsFolderCharsetEnabled()
  865. {
  866.   return IsFolderSelected();
  867. }
  868.  
  869. function IsPropertiesEnabled(command)
  870. {
  871.    try 
  872.    {
  873.       var folderTree = GetFolderTree();
  874.       var folderResource = GetSelectedFolderResource();
  875.  
  876.       // when servers are selected
  877.       // it should be "Edit | Properties..."
  878.       if (GetFolderAttribute(folderTree, folderResource, "IsServer") == "true")
  879.         goSetMenuValue(command, "valueGeneric");
  880.       else 
  881.         goSetMenuValue(command, isNewsURI(folderResource.Value) ? "valueNewsgroup" : "valueFolder");
  882.    }
  883.    catch (ex) 
  884.    {
  885.       // properties menu failure
  886.    }
  887.  
  888.    // properties should be enabled for folders and servers
  889.    // but not fake accounts
  890.    if (IsFakeAccount())
  891.      return false;
  892.  
  893.    var selection = folderTree.view.selection;
  894.    return (selection.count == 1);
  895. }
  896.  
  897. function IsViewNavigationItemEnabled()
  898. {
  899.     return IsFolderSelected();
  900. }
  901.  
  902. function IsFolderSelected()
  903. {
  904.     var folderTree = GetFolderTree();
  905.     var selection = folderTree.view.selection;
  906.     if (selection.count == 1)
  907.     {
  908.         var startIndex = {};
  909.         var endIndex = {};
  910.         selection.getRangeAt(0, startIndex, endIndex);
  911.         var folderResource = GetFolderResource(folderTree, startIndex.value);
  912.         return GetFolderAttribute(folderTree, folderResource, "IsServer") != "true";
  913.     }
  914.     else
  915.         return false;
  916. }
  917.  
  918. function IsMessageDisplayedInMessagePane()
  919. {
  920.   return (!IsMessagePaneCollapsed() && (GetNumSelectedMessages() > 0));
  921. }
  922.  
  923. function MsgDeleteFolder()
  924. {
  925.     var folderTree = GetFolderTree();
  926.     var selectedFolders = GetSelectedMsgFolders();
  927.     for (var i = 0; i < selectedFolders.length; i++)
  928.     {
  929.         var selectedFolder = selectedFolders[i];
  930.         var folderResource = selectedFolder.QueryInterface(Components.interfaces.nsIRDFResource);
  931.         var specialFolder = GetFolderAttribute(folderTree, folderResource, "SpecialFolder");
  932.         if (specialFolder != "Inbox" && specialFolder != "Trash")
  933.         {
  934.           var parentResource;
  935.  
  936.             var folder = selectedFolder.QueryInterface(Components.interfaces.nsIMsgFolder);
  937.             if (folder.flags & MSG_FOLDER_FLAG_VIRTUAL)
  938.             {
  939.                 if (gCurrentVirtualFolderUri == folderResource.Value)
  940.                   gCurrentVirtualFolderUri = null;
  941.                 parentResource = selectedFolder.parent.QueryInterface(Components.interfaces.nsIRDFResource);
  942.                 messenger.DeleteFolders(GetFolderDatasource(), parentResource, folderResource);
  943.                 continue;
  944.             }
  945.             var protocolInfo = Components.classes["@mozilla.org/messenger/protocol/info;1?type=" + selectedFolder.server.type].getService(Components.interfaces.nsIMsgProtocolInfo);
  946.  
  947.             // do not allow deletion of special folders on imap accounts
  948.             if ((specialFolder == "Sent" || 
  949.                 specialFolder == "Drafts" || 
  950.                 specialFolder == "Templates" ||
  951.                 (specialFolder == "Junk" && !CanRenameDeleteJunkMail(GetSelectedFolderURI()))) &&
  952.                 !protocolInfo.specialFoldersDeletionAllowed)
  953.             {
  954.                 var errorMessage = gMessengerBundle.getFormattedString("specialFolderDeletionErr",
  955.                                                     [specialFolder]);
  956.                 var specialFolderDeletionErrTitle = gMessengerBundle.getString("specialFolderDeletionErrTitle");
  957.                 promptService.alert(window, specialFolderDeletionErrTitle, errorMessage);
  958.                 continue;
  959.             }   
  960.             else if (isNewsURI(folderResource.Value))
  961.             {
  962.                 var unsubscribe = ConfirmUnsubscribe(selectedFolder);
  963.                 if (unsubscribe)
  964.                     UnSubscribe(selectedFolder);
  965.             }
  966.             else
  967.             {
  968.                 parentResource = selectedFolder.parent.QueryInterface(Components.interfaces.nsIRDFResource);
  969.                 messenger.DeleteFolders(GetFolderDatasource(), parentResource, folderResource);
  970.             }
  971.         }
  972.     }
  973. }
  974.  
  975. function SetFocusThreadPaneIfNotOnMessagePane()
  976. {
  977.   var focusedElement = WhichPaneHasFocus();
  978.  
  979.   if((focusedElement != GetThreadTree()) &&
  980.      (focusedElement != GetMessagePane()))
  981.      SetFocusThreadPane();
  982. }
  983.  
  984. // 3pane related commands.  Need to go in own file.  Putting here for the moment.
  985. function MsgNextMessage()
  986. {
  987.     GoNextMessage(nsMsgNavigationType.nextMessage, false );
  988. }
  989.  
  990. function MsgNextUnreadMessage()
  991. {
  992.     GoNextMessage(nsMsgNavigationType.nextUnreadMessage, true);
  993. }
  994. function MsgNextFlaggedMessage()
  995. {
  996.     GoNextMessage(nsMsgNavigationType.nextFlagged, true);
  997. }
  998.  
  999. function MsgNextUnreadThread()
  1000. {
  1001.     //First mark the current thread as read.  Then go to the next one.
  1002.     MsgMarkThreadAsRead();
  1003.     GoNextMessage(nsMsgNavigationType.nextUnreadThread, true);
  1004. }
  1005.  
  1006. function MsgPreviousMessage()
  1007. {
  1008.     GoNextMessage(nsMsgNavigationType.previousMessage, false);
  1009. }
  1010.  
  1011. function MsgPreviousUnreadMessage()
  1012. {
  1013.     GoNextMessage(nsMsgNavigationType.previousUnreadMessage, true);
  1014. }
  1015.  
  1016. function MsgPreviousFlaggedMessage()
  1017. {
  1018.     GoNextMessage(nsMsgNavigationType.previousFlagged, true);
  1019. }
  1020.  
  1021. function GetFolderNameFromUri(uri, tree)
  1022. {
  1023.     var folderResource = RDF.GetResource(uri);
  1024.  
  1025.     var db = tree.database;
  1026.  
  1027.     var nameProperty = RDF.GetResource('http://home.netscape.com/NC-rdf#Name');
  1028.  
  1029.     var nameResult;
  1030.     try {
  1031.         nameResult = db.GetTarget(folderResource, nameProperty , true);
  1032.     }
  1033.     catch (ex) {
  1034.         return "";
  1035.     }
  1036.  
  1037.     nameResult = nameResult.QueryInterface(Components.interfaces.nsIRDFLiteral);
  1038.     return nameResult.Value;
  1039. }
  1040.  
  1041. /* XXX hiding the search bar while it is focus kills the keyboard so we focus the thread pane */
  1042. function SearchBarToggled()
  1043. {
  1044.   var searchBox = document.getElementById('searchBox');
  1045.   if (searchBox)
  1046.   {
  1047.     var attribValue = searchBox.getAttribute("hidden") ;
  1048.     if (attribValue == "true")
  1049.     {
  1050.       /*come out of quick search view */
  1051.       if (gDBView && gDBView.viewType == nsMsgViewType.eShowQuickSearchResults)
  1052.         onClearSearch();
  1053.     }
  1054.     else
  1055.     {
  1056.       /*we have to initialize searchInput because we cannot do it when searchBox is hidden */
  1057.       var searchInput = GetSearchInput();
  1058.       searchInput.value="";
  1059.     }
  1060.   }
  1061.  
  1062.   for (var currentNode = top.document.commandDispatcher.focusedElement; currentNode; currentNode = currentNode.parentNode) {
  1063.     // But skip the last node, which is a XULDocument.
  1064.     if ((currentNode instanceof XULElement) && currentNode.hidden) {
  1065.       SetFocusThreadPane();
  1066.       return;
  1067.     }
  1068.   }
  1069. }
  1070.  
  1071. function SwitchPaneFocus(event)
  1072. {
  1073.   var folderTree = GetFolderTree();
  1074.   var threadTree = GetThreadTree();
  1075.   var messagePane = GetMessagePane();
  1076.  
  1077.   // Although internally this is actually a four-pane window, it is presented as
  1078.   // a three-pane -- the search pane is more of a toolbar.  So, shift among the
  1079.   // three main panes.
  1080.  
  1081.   var focusedElement = WhichPaneHasFocus();
  1082.   if (focusedElement == null)       // focus not on one of the main three panes?
  1083.     focusedElement = threadTree;    // treat as if on thread tree
  1084.  
  1085.   if (event && event.shiftKey)
  1086.   {
  1087.     // Reverse traversal: Message -> Thread -> Folder -> Message
  1088.     if (focusedElement == threadTree && !IsFolderPaneCollapsed())
  1089.       folderTree.focus();
  1090.     else if (focusedElement != messagePane && !IsMessagePaneCollapsed())
  1091.       SetFocusMessagePane();
  1092.     else
  1093.       threadTree.focus();
  1094.   }
  1095.   else
  1096.   {
  1097.     // Forward traversal: Folder -> Thread -> Message -> Folder
  1098.     if (focusedElement == threadTree && !IsMessagePaneCollapsed())
  1099.       SetFocusMessagePane();
  1100.     else if (focusedElement != folderTree && !IsFolderPaneCollapsed())
  1101.       folderTree.focus();
  1102.     else
  1103.       threadTree.focus();
  1104.   }
  1105. }
  1106.  
  1107. function SetFocusFolderPane()
  1108. {
  1109.     var folderTree = GetFolderTree();
  1110.     folderTree.focus();
  1111. }
  1112.  
  1113. function SetFocusThreadPane()
  1114. {
  1115.     var threadTree = GetThreadTree();
  1116.     threadTree.focus();
  1117. }
  1118.  
  1119. function SetFocusMessagePane()
  1120. {
  1121.     // XXX hack: to clear the focus on the previous element first focus
  1122.     // on the message pane element then focus on the main content window
  1123.     GetMessagePane().focus();
  1124.     GetMessagePaneFrame().focus();
  1125. }
  1126.  
  1127. function is_collapsed(element) 
  1128. {
  1129.   return (element.getAttribute('state') == 'collapsed');
  1130. }
  1131.  
  1132. function isCommandEnabled(cmd)
  1133. {
  1134.   var selectedFolders = GetSelectedMsgFolders();
  1135.   var numFolders = selectedFolders.length;
  1136.   if(numFolders !=1)
  1137.     return false;
  1138.  
  1139.   var folder = selectedFolders[0];
  1140.   if (!folder)
  1141.     return false;
  1142.   else
  1143.     return folder.isCommandEnabled(cmd);
  1144.  
  1145. }
  1146.  
  1147. function IsFakeAccount() {
  1148.   try {
  1149.     var folderResource = GetSelectedFolderResource();
  1150.     return (folderResource.Value == "http://home.netscape.com/NC-rdf#PageTitleFakeAccount");
  1151.   }
  1152.   catch(ex) {
  1153.   }
  1154.   return false;
  1155. }
  1156.  
  1157. //
  1158. // This function checks if the configured junk mail can be renamed or deleted.
  1159. //
  1160. function CanRenameDeleteJunkMail(aFolderUri)
  1161. {
  1162.   if (!aFolderUri)
  1163.     return false;
  1164.  
  1165.   // Go through junk mail settings for all servers and see if the folder is set/used by anyone.
  1166.   try
  1167.   {
  1168.     var allServers = accountManager.allServers;
  1169.  
  1170.     for (var i=0;i<allServers.Count();i++)
  1171.     {
  1172.       var currentServer = allServers.GetElementAt(i).QueryInterface(Components.interfaces.nsIMsgIncomingServer);
  1173.       var settings = currentServer.spamSettings;
  1174.       // If junk mail control or move junk mail to folder option is disabled then
  1175.       // allow the folder to be removed/renamed since the folder is not used in this case.
  1176.       if (!settings.level || !settings.moveOnSpam)
  1177.         continue;
  1178.       if (settings.spamFolderURI == aFolderUri)
  1179.         return false;
  1180.     }
  1181.   }
  1182.   catch(ex)
  1183.   {
  1184.       dump("Can't get all servers\n");
  1185.   }
  1186.   return true;
  1187. }
  1188.